package com.ehais.util;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

import com.ehais.model.Commands;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.lang.reflect.Type;
import java.util.List;


public class AsciiToHex {

    private static final String TAG="WifiUtil";


    private static String asciiToHex(String asciiStr) {
        char[] chars = asciiStr.toCharArray();
        StringBuilder hex = new StringBuilder();
        for (char ch : chars) {
            hex.append(Integer.toHexString((int) ch));
        }
        return hex.toString();
    }


    public static String hexToAscii(String hex) {
        StringBuilder output = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String str = hex.substring(i, i + 2);
            output.append((char) Integer.parseInt(str, 16));
        }
        return output.toString().trim();
    }


    /**
     * String 转 byte[]
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToByte(String hexString) {
        if (hexString == null || hexString.length() == 0 || hexString.trim().length() == 0) {
            return null;
        }
        //转大写，去空格
        hexString = hexString.toUpperCase().replace(" ", "");
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * byte[]转String
     * @param hexByte
     * @return
     */
    public static String hexByteToString(byte[] hexByte){
        if(hexByte == null){
            return null;
        }
        StringBuilder hex = new StringBuilder();

        for (byte b : hexByte) {
            hex.append(HEXES[(b >> 4) & 0x0F]);
            hex.append(HEXES[b & 0x0F]);
        }
        return hex.toString();
    }
    private static final char[] HEXES = {
            '0', '1', '2', '3',
            '4', '5', '6', '7',
            '8', '9', 'A', 'B',
            'C', 'D', 'E', 'F'
    };
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 生成CRC16-Modbus校验码并返回校验是否成功
     * @param
     * @return
     */
    public static boolean getCRC16Modbus(byte[] bytes){
        int CRC = 0x0000FFFF;
        int POLYNOMIAL = 0x0000A001;
        //长度-2，去除校验为
        int i, j;
        for (i = 0; i < bytes.length-2 ; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        //假如校验相反则取消注释
//        CRC = ((CRC & 0x0000FF00) >> 8) | ((CRC & 0x000000FF) << 8);
        String crc1 = String.format("%04X",CRC);
        String crc2 =  String.format("%02X",bytes[bytes.length-1])+String.format("%02X",bytes[bytes.length-2]);
        Log.i(TAG,"源码："+crc1+"---系统："+crc2);
        if(crc1.equals(crc2)){
            return true;
        }
        return false;
    }

    /**
     * 在原有的byte上生成校验
     * @param bytes
     * @return
     */
    public static byte[] setCRC16Modbus(byte[] bytes){
        int CRC = 0x0000FFFF;
        int POLYNOMIAL = 0x0000A001;
        byte[] bt = new byte[2];
        //长度-2，去除校验为
        int i, j;
        for (i = 0; i < bytes.length-2 ; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        CRC = ((CRC & 0x0000FF00) >> 8) | ((CRC & 0x000000FF) << 8);
        bt = hexStringToByte(String.format("%04X",CRC));
        bytes[bytes.length-2]=bt[0];
        bytes[bytes.length-1]=bt[1];
        return bytes;
    }

    /**
     * 计算数值
     * @param b 原数组
     * @param index，开始标志位
     * @return  返回float型数据
     */
    public static float byteToFloat(byte[] b, int index) {
        int l;
        l = b[index + 3];
        l &= 0xff;
        l |= ((long) b[index + 2] << 8);
        l &= 0xffff;
        l |= ((long) b[index + 1] << 16);
        l &= 0xffffff;
        l |= ((long) b[index + 0] << 24);
        return Float.intBitsToFloat(l);
    }

    /**
     * 两位byte转int
     * @param bt1 0
     * @param bt2 1
     * @return int
     */
    public static int byteGetInt(byte bt1,byte bt2){
        return (bt1 & 0xff) << 8 | (bt2 & 0xff);
    }


    public static String printHexString(byte[] b) {
        String res = "";
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            res += hex;
        }

        return res;
    }


    public static String chksum(String out){
        int sum = 0;
        out = out.toUpperCase();
        System.out.println(out);
        for(int i = 1 ; i < out.length() ; i++) {
            char c = out.charAt(i);
            int ascii = (int) c;
//            System.out.println(out.substring(i, i+1)+"==>"+ascii);
            sum += ascii;
        }

//        System.out.println("sum:"+sum);
        String sum_bit = Integer.toString(sum, 2);
//        System.out.println("bit:"+sum_bit);

        String oppo = numberBeforeFillZero(sum_bit,16);// String.format("%016d", Integer.parseInt(sum_bit));
//        System.out.println(" oppo:"+oppo);
        StringBuilder builder = new StringBuilder();
        for(int i = 0 ; i < oppo.length() ; i++) {
            builder.append(oppo.substring(i, i+1).equals("0") ? "1" : "0");
        }
//        System.out.println("_oppo:"+builder.toString());

        int _result = Integer.parseInt(builder.toString(),2);
//        System.out.println("_result:"+_result);
        int result = _result + 1;
//        System.out.println(" result:"+result);

        String res = String.format("%04x", result).toUpperCase();
        return res;

    }

    public static String numberBeforeFillZero(String str,int len) {
        if(str.length() >= len) return str;

        int b = len - str.length();

        String z = "";
        for(int i = 0 ; i < b ; i++)z +="0";
        return z + str;


    }

    /**
     * byte数组转十六位字符串（不带空格）
     * @param bytes 待转换的byte数组
     */
    public static String toHexAscii(byte[] bytes) {
        int len = bytes.length;
        StringWriter sw = new StringWriter(len * 2);
        for (int i = 0; i < len; ++i)
            addHexAscii(bytes[i], sw);
        return sw.toString();
    }
    /**
     * byte转16位并拼接
     * @param b     数组
     * @param sw    字符串
     */
    static void addHexAscii(byte b, StringWriter sw) {
        int ub = unsignedPromote(b);
        int h1 = ub / 16;
        int h2 = ub % 16;
        sw.write(toHexDigit(h1));
        sw.write(toHexDigit(h2));
    }

    /**
     * byte取补位数据
     * @param b 数组
     * @return
     */
    public static int unsignedPromote(byte b) {
        return b & 0xff;
    }

    /* note: we do no arg. checking, because     */
    /* we only ever call this from addHexAscii() */
    /* above, and we are sure the args are okay  */
    private static char toHexDigit(int h) {
        char out;
        if (h <= 9) out = (char) (h + 0x30);
        else out = (char) (h + 0x37);
        //System.err.println(h + ": " + out);
        return out;
    }




    public static JSONObject getCommandData(Context context){
        try {
            //获取本地的Json文件
            AssetManager assetManager = context.getAssets();
            InputStream open = assetManager.open("command.json");
            InputStreamReader isr = new InputStreamReader(open, "UTF-8");
            //包装字符流,将字符流放入缓存里
            BufferedReader br = new BufferedReader(isr);
            String line;
            //StringBuilder和StringBuffer功能类似,存储字符串
            StringBuilder builder = new StringBuilder();
            while ((line = br.readLine()) != null) {
                //append 被选元素的结尾(仍然在内部)插入指定内容,缓存的内容依次存放到builder中
                builder.append(line);

            }
            br.close();
            isr.close();

//            Log.i(TAG,"command.json::::::::::::::::"+builder);
            Gson gson = new Gson();

            JSONObject jsonObject = new JSONObject(builder.toString());

            return jsonObject;

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }



}
